<?php

namespace app\libs;

use Laf\Session;
use mon\env\Config;
use mon\util\Instance;
use mon\util\Container;
use app\model\MenuModel;
use mon\template\View as Template;

/**
 * 视图引擎工具，结合layui快速生成视图
 * 
 * @author Mon <985558837@qq.com>
 * @version 1.0.0
 */
class View extends Template
{
    use Instance;

    /**
     * 构造方法
     *
     * @param string $path 视图目录路径
     * @param string $ext  视图文件后缀
     */
    function __construct($path = "", $ext = '')
    {
        $path = empty($path) ? APP_PATH . '/view/' : $path;
        $ext = empty($ext) ? 'html' : $ext;
        $this->path = $path;
        $this->ext = $ext;
        $this->assign('container', Container::instance());
    }

    /**
     * 获取静态资源方法
     *
     * @param string $path  资源路径
     * @param array $params 附加参数
     * @return string
     */
    public function assets($path, $params = [])
    {
        $url = Container::instance()->url->build($path, $params);
        return str_replace('/index.php', '', $url);
    }

    /**
     * 校验用户权限
     *
     * @param string $path
     * @return boolean
     */
    public function checkAuth($path)
    {
        $uid = Session::instance()->get(Config::instance()->get('admin.admin_session_key') . '.id', 0);
        return Container::instance()->auth->check($path, $uid);
    }

    /**
     * 生成页面Heading
     *
     * @param string $path 指定的path
     * @return string
     */
    public static function build_heading($path = null, $container = true)
    {
        $title = $content = '';
        $path = is_null($path) ? Container::instance()->request->pathInfo() : $path;
        // 根据当前的URI自动匹配父节点的标题和备注
        $data = MenuModel::instance()->getInfo(['name' => $path]);
        if ($data) {
            $title = $data['title'];
            $content = $data['remark'];
        }
        $result = '<div class="panel-lead"><strong>' . $title . '</strong>' . $content . '</div>';
        if ($container) {
            $result = '<div class="panel-heading">' . $result . '</div>';
        }
        return $result;
    }

    /**
     * 生成表格操作按钮栏
     *
     * @param array $btns 按钮组
     * @param array $attr 按钮属性值
     * @return string
     */
    public function build_toolbar(array $btns = null, array $attr = [])
    {
        $path = Container::instance()->request->pathinfo();
        $uid  = Session::instance()->get(Config::instance()->get('admin.admin_session_key') . '.id', 0);
        $btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del'];
        $btnAttr = [
            'refresh' => ['javascript:;', 'btn btn-primary btn-refresh', 'fa fa-refresh', '', '刷新'],
            'add'     => ['javascript:;', 'btn btn-success btn-add', 'fa fa-plus', '新增', '新增'],
            'edit'    => ['javascript:;', 'btn btn-success btn-edit', 'fa fa-pencil', '编辑', '编辑'],
            'del'     => ['javascript:;', 'btn btn-danger btn-del', 'fa fa-trash', '删除', '删除'],
            'publish' => ['javascript:;', 'btn btn-info btn-publish', 'fa fa-upload', '发布', '发布'],
            'search'  => ['javascript:;', 'btn btn-warning btn-search', 'fa fa-search', '搜索', '搜索'],
        ];
        $white = ['refresh', 'search'];
        $btnAttr = array_merge($btnAttr, $attr);
        $html = [];
        foreach ($btns as $k => $v) {
            $checkPath = $path . '/' . $v;
            // 如果未定义或没有权限则不渲染
            if (!isset($btnAttr[$v]) || (!in_array($v, $white) && !Container::instance()->auth->check($checkPath, $uid))) {
                continue;
            }
            list($href, $class, $icon, $text, $title) = $btnAttr[$v];
            $html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '"><i class="' . $icon . '"></i> ' . $text . '</a>';
        }
        return implode(' ', $html);
    }

    /**
     * 生成layui-select
     *
     * @param string $name      name值
     * @param array $data       option列表
     * @param array $selected   选中的option
     * @param array $attrs      附加属性
     * @param boolean $keyVal   data是否为key-value数据, 否则使用id-title的二维数组形式处理数据
     * @return string
     */
    public function build_select($name, $data = [], $selecteds = [], $attrs = [], $keyVal = false)
    {
        $attr = $this->parseAttr($attrs);
        $options = [];
        foreach ($data as $key => $value) {
            $val = $keyVal ? $key : $value['id'];
            $title = $keyVal ? $value : $value['title'];
            $selected = in_array($val, $selecteds) ? 'selected' : '';
            $options[] = '<option value="' . $val . '" ' . $selected . ' >' . $title . '</option>';
        }
        $html = '<select name="' . $name . '" ' . $attr . ' lay-filter="' . $name . '">' . implode(' ', $options) . '</select>';
        return $html;
    }

    /**
     * 生成layui-radio组
     *
     * @param string $name 		name值
     * @param array $data 		列表数据
     * @param mixed $selected	选中的redio
     * @param array $attrs      附加属性
     * @param boolean $keyVal   data是否为key-value数据, 否则使用id-title的二维数组形式处理数据
     * @return string
     */
    public function build_radios($name, $data = [], $selected = null, $attrs = [], $keyVal = false)
    {
        $attr = $this->parseAttr($attrs);
        $redios = [];
        foreach ($data as $key => $value) {
            $val = $keyVal ? $key : $value['id'];
            $title = $keyVal ? $value : $value['title'];
            $checked = $val == $selected ? 'checked' : '';
            $redios[] = '<label><input type="radio" name="' . $name . '" value="' . $val . '" title="' . $title . '" ' . $attr . ' ' . $checked . ' /></label>';
        }

        return implode(' ', $redios);
    }

    /**
     * 生成layui-checkbox复选按钮组
     *
     * @param string $name      name值
     * @param array $data       列表数据
     * @param array $selected   选中列表
     * @param array $attrs      附加属性
     * @param boolean $keyVal   data是否为key-value数据, 否则使用id-title的二维数组形式处理数据
     * @return string
     */
    public function build_checkboxs($name, $data = [], $selected = [], $attrs = [], $keyVal = false)
    {
        $attr = $this->parseAttr($attrs);
        $html = [];
        foreach ($data as $key => $value) {
            $val = $keyVal ? $key : $value['id'];
            $title = $keyVal ? $value : $value['title'];
            $checked = in_array($val, $selected) ? 'checked' : '';
            $html[] = '<input type="checkbox" name="' . $name . '" value="' . $val . '" title="' . $title . '" ' . $attr . ' lay-skin="primary" ' . $checked . ' />';
        }
        return implode(' ', $html);
    }

    /**
     * 生成layui-switch开关
     * 
     * @param string $name      name值
     * @param boolean $checked  是否选中
     * @param string $value     选中值
     * @param array $text       开关提示
     * @param array $attrs      附加属性
     * @return string
     */
    public function build_switch($name, $checked = false, $value = 1, $text = ['开启', '关闭'], $attrs = [])
    {
        $attr = $this->parseAttr($attrs);
        $laychecked = $checked ? 'checked' : '';
        $laytext = implode('|', $text);
        $html = "<input type='checkbox' name='{$name}' value='{$value}' lay-skin='switch' lay-text='{$laytext}' {$attr} {$laychecked}>";
        return $html;
    }

    /**
     * 生成input输入框
     *
     * @param string $name  name值
     * @param string $type  type值
     * @param string $value 默认值
     * @param array $attrs  附加属性
     * @param boolean $lay  启用layui
     * @return string
     */
    public function build_input($name, $type, $value = '', $attrs = [], $lay = true)
    {
        if ($lay) {
            // 兼容attrs定义class
            $attrs['class'] = isset($attrs['class']) ? ($attrs['class'] . ' layui-input') : 'layui-input';
        }
        $attr = $this->parseAttr($attrs);
        $html = "<input type='{$type}' name='{$name}' value='{$value}' {$attr} />";
        return $html;
    }

    /**
     * 解析附加属性
     *
     * @param array $attrs 属性
     * @return string
     */
    protected function parseAttr($attrs = [])
    {
        $attr = [];
        foreach ($attrs as $tag => $value) {
            if (is_int($tag)) {
                $attr[] = $value;
            } else {
                $attr[] =  $tag . '="' . $value . '"';
            }
        }
        return implode(' ', $attr);
    }
}
